package com.codeoss.framework.codegenerator;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import com.codeoss.framework.data.metadata.Column;
import com.codeoss.framework.data.metadata.Table;
import com.codeoss.framework.util.DataTypeConstants;

public class ModelGenerator {
	public String generate(Table table){
		StringBuilder sb=new StringBuilder();
		List<Column> columnList=table.getColumnList();
		Set<String> importSet=new HashSet<String>();
		importSet.add("org.apache.ibatis.type.JdbcType");
		importSet.add("com.baomidou.mybatisplus.annotation.TableField");
		for(int i=0;i<columnList.size();i++) {
			Column column=columnList.get(i);
			String dataType=column.getDataType();
			if(DataTypeConstants.DATA_TYPE_BIGDECIMAL.equals(dataType)) {
				importSet.add("java.math.BigDecimal");
			}else if(DataTypeConstants.DATA_TYPE_DATETIME.equals(dataType)) {
				importSet.add("java.sql.Timestamp");
			}else if(DataTypeConstants.DATA_TYPE_DATE.equals(dataType)) {
				importSet.add("java.sql.Date");
			}else if(DataTypeConstants.DATA_TYPE_TIME.equals(dataType)) {
				importSet.add("java.sql.Time");
			}else if(DataTypeConstants.DATA_TYPE_BOOLEAN.equals(dataType)) {
				importSet.add("com.codeoss.framework.mybatisplus.BooleanTypeHandler");
			}
		}
		sb.append("package ");
		sb.append(table.getPackageName()).append(".model;");
		Iterator<String> importIt=importSet.iterator();
		while(importIt.hasNext()) {
			String importString=importIt.next();
			sb.append("import ").append(importString).append(";");
		}
		Table superTable=table.getSuperTable();
		if(superTable!=null) {
			String tableName=superTable.getTableName();
			if("base_table".equals(tableName)) {
				sb.append("import com.codeoss.framework.model.BaseModel; ");
			}else {
				sb.append("import com.codeoss.framework.model.TreeModel; ");
			}
		}
		sb.append("public class ");
		String className=CodeGeneratorUtil.getClassName(table);
		sb.append(className);
		if(superTable!=null) {
			sb.append(" extends ");
			String tableName=superTable.getTableName();
			if("base_table".equals(tableName)) {
				sb.append("BaseModel ");
			}else {
				sb.append("TreeModel ");
			}
		}
		sb.append("{");
		for(int i=0;i<columnList.size();i++) {
			Column column=columnList.get(i);
			String typeName=getTypeName(column);
			if("Boolean".equals(typeName)) {
				sb.append("@TableField(typeHandler=BooleanTypeHandler.class,jdbcType=JdbcType.VARCHAR)");
			}else {
				String dataType=column.getDataType();
				if(DataTypeConstants.DATA_TYPE_STRING.equals(dataType)) {
					sb.append("@TableField(jdbcType=JdbcType.VARCHAR)");
				}else if(DataTypeConstants.DATA_TYPE_INTEGER.equals(dataType)) {
					sb.append("@TableField(jdbcType=JdbcType.INTEGER)");
				}else if(DataTypeConstants.DATA_TYPE_LONG.equals(dataType)) {
					sb.append("@TableField(jdbcType=JdbcType.BIGINT)");
				}else if(DataTypeConstants.DATA_TYPE_BIGDECIMAL.equals(dataType)) {
					sb.append("@TableField(jdbcType=JdbcType.DECIMAL)");
				}else if(DataTypeConstants.DATA_TYPE_DATETIME.equals(dataType)) {
					sb.append("@TableField(jdbcType=JdbcType.TIMESTAMP)");
				}else if(DataTypeConstants.DATA_TYPE_DATE.equals(dataType)) {
					sb.append("@TableField(jdbcType=JdbcType.DATE)");
				}else if(DataTypeConstants.DATA_TYPE_TIME.equals(dataType)) {
					sb.append("@TableField(jdbcType=JdbcType.TIME)");
				}else if(DataTypeConstants.DATA_TYPE_BINARY.equals(dataType)) {
					sb.append("@TableField(jdbcType=JdbcType.BINARY)");
				}
			}
			sb.append(" private ");
			sb.append(typeName);
			sb.append(" ").append(column.getProperty()).append(";");
		}
		
		for(int i=0;i<columnList.size();i++) {
			Column column=columnList.get(i);
			sb.append(" public ");
			String typeName=getTypeName(column);
			sb.append(typeName);
			sb.append(" get");
			String property=column.getProperty();
			String prop=property.substring(0, 1).toUpperCase()+property.substring(1);
			sb.append(prop).append("(){ return ").append(property).append(";}");
			
			sb.append(" public void set");
			sb.append(prop).append("(").append(typeName).append(" ").append(property).append("){");
			sb.append("this.").append(property).append("=").append(property).append(";}");
		}
		sb.append("}");
		return sb.toString();
	}
	
	private String getTypeName(Column column) {
		String typeName="";
		String dataType=column.getDataType();
		if(DataTypeConstants.DATA_TYPE_STRING.equals(dataType)) {
			typeName="String";
		}else if(DataTypeConstants.DATA_TYPE_INTEGER.equals(dataType)) {
			typeName="Integer";
		}else if(DataTypeConstants.DATA_TYPE_BIGDECIMAL.equals(dataType)) {
			typeName="BigDecimal";
		}else if(DataTypeConstants.DATA_TYPE_LONG.equals(dataType)) {
			typeName="Long";
		}else if(DataTypeConstants.DATA_TYPE_BOOLEAN.equals(dataType)) {
			typeName="Boolean";
		}else if(DataTypeConstants.DATA_TYPE_DATETIME.equals(dataType)) {
			typeName="Timestamp";
		}else if(DataTypeConstants.DATA_TYPE_DATE.equals(dataType)) {
			typeName="Date";
		}else if(DataTypeConstants.DATA_TYPE_TIME.equals(dataType)) {
			typeName="Time";
		}else if("binary".equals(dataType)) {
			typeName="Object";
		}
		return typeName;
	}
}
